<template>
  <BePage class="dashboard">
    <!-- 顶部入口 -->
    <div class="top-entry-list">
      <div class="top-entry__item" v-for="(item, index) in topEntryList" :key="index">
        <div class="top-entry__item-inner">
          <div class="top-entry__item-image">
            <img :src="item.img" />
          </div>
          <div class="top-entry__item-content">
            <h3 class="title">{{ item.name }}</h3>

            <p class="num">{{ topEntryListTotal[item.prop01] || 0 }} {{ item.prop02 ? ' | ' : '' }} {{ item.prop02 ? topEntryListTotal[item.prop02] || null : '' }}</p>
          </div>
        </div>
      </div>
    </div>
    <!-- 数据中心 -->
    <div class="data-center-sidebar">
      <div class="data-center-display" style="display: flex; align-items: center; justify-content: center">
        <h1 style="position: absolute; top: 20px; left: 20px; font-size: 1.2rem; color: #fff">系统运行数据供给流通</h1>
        <img class="data-center-bg" src="@/assets/img/dashboard/data-center-bg1.png" />
        <!-- <div class="data-info" style="top: 24%; left: 19%">
          <div class="info-item top-info-item">
            <p class="text">文件数:1147</p>
            <p class="text">防护率：100%</p>
          </div>
          <div class="info-item bottom-info-item">
            <p class="text">文件数:854</p>
            <p class="text">防护率：100%</p>
          </div>
        </div>

        <div class="data-info right-data-info">
          <div class="info-item top-info-item">
            <p class="text">文件数:2875</p>
            <p class="text">防护率：100%</p>
          </div>
          <div class="info-item bottom-info-item">
            <p class="text">文件数:540</p>
            <p class="text">防护率：100%</p>
          </div>
        </div>
        <div class="arrow-wrap left-arrow-wrap">
          <div class="arrow-item left-arrow-item">
            <p class="text">数据供给</p>
            <img class="arrow-pic" src="@/assets/img/dashboard/data-center-left-arrow.png" />
          </div>
          <div class="arrow-item right-arrow-item">
            <p class="text">数据采集</p>
            <img class="arrow-pic" src="@/assets/img/dashboard/data-center-right-arrow.png" />
          </div>
        </div>
        <div class="arrow-wrap right-arrow-wrap">
          <div class="arrow-item right-arrow-item">
            <p class="text">数据供给</p>
            <img class="arrow-pic" src="@/assets/img/dashboard/data-center-right-arrow.png" />
          </div>
          <div class="arrow-item left-arrow-item">
            <p class="text">数据采集</p>
            <img class="arrow-pic" src="@/assets/img/dashboard/data-center-left-arrow.png" />
          </div>
        </div> -->
      </div>
      <div class="right-wrap">
        <div class="right-tools">
          <div class="right-title">工具箱</div>
          <div class="tools-list">
            <div class="tools-item" v-for="(item, index) in toolsList" :key="index">
              <a style="text-align: center" @click="handleToolClick(item.url)">
                <img class="icon" :src="item.img" />
                <p class="text">{{ item.name }}</p>
              </a>
            </div>
          </div>
        </div>
        <div class="right-chart">
          <div class="right-title">敏感数据类型分布</div>
          <WordCloudChart :chartData="dataTypeStatisticList" />
        </div>
      </div>
    </div>
    <!-- 图表和数据 -->
    <div class="data-table-wrap">
      <div class="data-table-item">
        <a-tabs :activeKey="dataSupplyTab" @change="handleDataSupplyTabChange" class="data-table-tabs">
          <a-tab-pane v-for="t in dataSupply" :key="t.key" :tab="t.title" />
        </a-tabs>
        <!-- 详细数据 -->
        <div class="data-info-list">
          <div class="data-info__item">
            <div class="data-info__item-inner">
              <div class="info">
                <h3 class="title">添加{{ dataSupplyType }}总数</h3>
                <p class="num">{{ dataSupplyList.totalNum || 0 }}</p>
              </div>
              <img class="icon" src="@/assets/img/dashboard/data-info-icon-01.png" />
            </div>
          </div>
          <div class="data-info__item">
            <div class="data-info__item-inner">
              <div class="info">
                <h3 class="title">在线{{ dataSupplyType }}数</h3>
                <p class="num">{{ dataSupplyList.onlineNum }}</p>
              </div>
              <img class="icon" src="@/assets/img/dashboard/data-info-icon-02.png" />
            </div>
          </div>
          <div class="data-info__item">
            <div class="data-info__item-inner">
              <div class="info">
                <h3 class="title">离线{{ dataSupplyType }}数</h3>
                <p class="num">{{ dataSupplyList.offlineNum }}</p>
              </div>
              <img class="icon" src="@/assets/img/dashboard/data-info-icon-03.png" />
            </div>
          </div>
        </div>
        <div class="table-wrapper">
          <BeTable
            :columns="columns"
            :canResize="false"
            :showSearch="false"
            ref="dataSupplyTable"
            :data-source="dataSupplyList.details"
            :pagination="false"
            :bordered="false"
            :scroll="{ y: 200 }"
            :clearPadding="true"
          >
            <template #bodyCell="{ column, record }">
              <!-- 供给状态 -->
              <template v-if="column.key === 'dataType'">
                <template v-if="record.dataType">
                  <span :class="record.dataType === '在线' ? 'status-online' : 'status-offline'">
                    {{ record.dataType }}
                  </span>
                </template>
              </template>
              <!-- 添加水印状态 -->
              <template v-if="column.key === 'status'">
                <template v-if="record.status">
                  <span class="dot" :class="record.status === '成功' ? 'dot-success' : 'dot-fail'"></span>
                  <span :class="record.status === '成功' ? 'status-success' : 'status-fail'">{{ record.status }}</span>
                </template>
              </template>
              <!-- 操作列 -->
              <!-- <template v-else-if="column.key === 'action'">
                <a class="detail-link">详情</a>
              </template> -->
            </template>
          </BeTable>
        </div>
      </div>
      <div class="data-table-item">
        <a-tabs class="data-table-tabs">
          <a-tab-pane key="risk" tab="风险情况">
            <!-- 数据展示卡片 -->
            <div class="data-info-list">
              <div class="data-info__item">
                <div class="data-info__item-inner">
                  <div class="info">
                    <h3 class="title">处置数</h3>
                    <p class="num">{{ top5EventType.dealedCount }}</p>
                  </div>
                  <img class="icon" src="@/assets/img/dashboard/data-info-icon-04.png" />
                </div>
              </div>
              <div class="data-info__item">
                <div class="data-info__item-inner">
                  <div class="info">
                    <h3 class="title">未处置数</h3>
                    <p class="num">{{ top5EventType.waitingDealCount }}</p>
                  </div>
                  <img class="icon" src="@/assets/img/dashboard/data-info-icon-05.png" />
                </div>
              </div>
              <div class="data-info__item">
                <div class="data-info__item-inner">
                  <div class="info">
                    <h3 class="title">风险处置占比</h3>
                    <p class="num">{{ top5EventType.totalRate }}%</p>
                  </div>
                  <img class="icon" src="@/assets/img/dashboard/data-info-icon-06.png" />
                </div>
              </div>
            </div>

            <!-- 图表展示区域 -->
            <div class="chart-wrap">
              <div class="chart-item">
                <BottomBarChart :chartData="dataTypeRanking" v-if="dataTypeRanking.length > 0" />
                <div v-else class="white-text">暂无数据</div>
              </div>
              <div class="chart-item">
                <BottomLineChart :chartData="dataTrend" v-if="dataTrend.length > 0" />
                <div v-else class="white-text">暂无数据</div>
              </div>
            </div>
          </a-tab-pane>
        </a-tabs>
      </div>
    </div>
  </BePage>
</template>
<script lang="ts" setup>
import TOOLS_ICON_01 from '@/assets/img/dashboard/tools-icon-01.png'
import TOOLS_ICON_02 from '@/assets/img/dashboard/tools-icon-02.png'
import TOOLS_ICON_03 from '@/assets/img/dashboard/tools-icon-03.png'
import TOOLS_ICON_04 from '@/assets/img/dashboard/tools-icon-04.png'
import TOOLS_ICON_05 from '@/assets/img/dashboard/tools-icon-05.png'
import TOOLS_ICON_06 from '@/assets/img/dashboard/tools-icon-06.png'
import TOP_ENTRY_01 from '@/assets/img/dashboard/top-entry-01.png'
import TOP_ENTRY_02 from '@/assets/img/dashboard/top-entry-02.png'
import TOP_ENTRY_03 from '@/assets/img/dashboard/top-entry-03.png'
import TOP_ENTRY_04 from '@/assets/img/dashboard/top-entry-04.png'
import TOP_ENTRY_05 from '@/assets/img/dashboard/top-entry-05.png'
import BottomBarChart from './components/BottomBarChart.vue'
import BottomLineChart from './components/BottomLineChart.vue'
import WordCloudChart from './components/WordCloudChart.vue'
import {
  getHomeSituation,
  getHomeDataTypeStatistic,
  getHomeChangeDetail,
  getHomesql,
  getHomeApiCount,
  getHomeSensitiveStatistic,
  getHomeRiskLevelTrendLast5Days,
  getHomeListTop5EventType,
  getHomeStatisticsEventDealStatus
} from '@/api/dashboard/index'
import { useRouter } from 'vue-router'
const router = useRouter()
interface TopEntryList {
  dealedCount?: number
  waitingDealCount?: number
  totalCount?: number
  totalRate?: number
}
defineOptions({
  name: 'Dashboard'
})

// state
// 顶部入口数据
const topEntryList = ref([
  { id: 1, name: '数据库', img: TOP_ENTRY_01, prop01: 'sqldata' },
  { id: 1, name: '数据表 | 涉敏数据表', img: TOP_ENTRY_02, prop01: 'tableCount', prop02: 'sensitiveTableCount' },
  { id: 2, name: '字段数 | 涉敏字段数', img: TOP_ENTRY_03, prop01: 'fieldCount', prop02: 'sensitiveFieldCount' },
  { id: 3, name: '文件数 | 涉敏文件数', img: TOP_ENTRY_04, prop01: 'fileCount', prop02: 'sensitiveFileCount' },
  { id: 4, name: 'API数 | 涉敏API数', img: TOP_ENTRY_05, prop01: 'apiCount', prop02: 'sensitiveApiCount' }
])
const topEntryListTotal = ref<any>({
  sqldata: 0,
  tableCount: 0,
  fieldCount: 0,
  fileCount: 0,
  apiCount: 0,
  sensitiveTableCount: 0,
  sensitiveFieldCount: 0,
  sensitiveFileCount: 0,
  sensitiveApiCount: '9'
})
//敏感数据类型分布数据
const dataTypeStatisticList = ref([])
const top5EventType = ref<TopEntryList>({
  dealedCount: 0,
  totalCount: 0,
  waitingDealCount: 0,
  totalRate: 0
})

const handleToolClick = (item: any) => {
  window.parent.postMessage({
    type: 'ROUTE_NAVIGATE', // 消息类型，用于父级识别
    payload: {
      path: item // 具体的路由路径
    }
  })
}

// 工具箱列表
const toolsList = ref([
  { id: 1, name: '数据水印', img: TOOLS_ICON_01, url: '/capability/data-mask/data-toolbox-watermark' },
  { id: 2, name: '数据脱敏', img: TOOLS_ICON_02, url: '/capability/data-mask/data-toolbox-desensitization' },
  { id: 3, name: '数据水印溯源', img: TOOLS_ICON_03, url: '/capability/data-mask/data-toolbox-traceability' },
  { id: 4, name: '敏感数据检测', img: TOOLS_ICON_04, url: '/capability/data-mask/data-toolbox-sensitive' },
  { id: 5, name: '数据加密', img: TOOLS_ICON_05, url: '' },
  { id: 6, name: '数据解密', img: TOOLS_ICON_06, url: '' }
])

// const listOfData = ref([
//   { id: 1, time: '2025-03-26 08:29:20', type: 'txt', status: '在线', result: '成功' },
//   { id: 2, time: '2025-03-26 08:29:20', type: 'xls', status: '在线', result: '成功' },
//   { id: 3, time: '2025-03-26 08:29:20', type: 'pdf', status: '在线', result: '成功' },
//   { id: 4, time: '2025-03-26 08:29:20', type: 'word', status: '在线', result: '成功' },
//   { id: 5, time: '2025-03-26 08:29:20', type: 'word', status: '离线', result: '失败' },
//   { id: 6, time: '2025-03-26 08:29:20', type: 'word', status: '离线', result: '失败' },
//   { id: 7, time: '2025-03-26 08:29:20', type: 'word', status: '离线', result: '失败' }
// ])
/**数据供给情况、添加水印供给情况、脱敏供给情况 Tab*/
const dataSupply = ref<{ key: string; title: string; type: string }[]>([
  { key: 'data', title: '数据供给情况', type: '供给' },
  { key: 'watermark', title: '添加水印供给情况', type: '水印' },
  { key: 'mask', title: '脱敏供给情况', type: '脱敏' }
])
// 表格数据
const columns = ref([
  { title: '任务名称', dataIndex: 'taskName', key: 'taskName', width: 140 },
  { title: '文件名称', dataIndex: 'fileName', key: 'fileName', width: 160 },
  { title: '添加水印时间', dataIndex: 'createTime', key: 'createTime', width: 140, fixed: 'left' },
  { title: '添加水印类型', dataIndex: 'fileType', key: 'fileType', width: 100 },
  { title: '供给状态', dataIndex: 'status', key: 'status', width: 120 },
  { title: '添加水印状态', dataIndex: 'dataType', key: 'dataType', width: 120 }
  // { title: '添加水印详情', dataIndex: 'dataType', key: 'dataType', width: 100 }
  // { title: '操作', dataIndex: 'action', key: 'action', width: 50, fixed: 'right' }
])
const dataSupplyTable = ref<any>(null)
const dataSupplyTab = ref<string>('data')
const dataSupplyType = ref<string>('供给')
const dataSupplyList = ref({
  totalNum: 0,
  onlineNum: 0,
  offlineNum: 0,
  details: []
})
const dataTypeRanking = ref([])
const dataTrend = ref([])

const handleDataSupplyTabChange = (key: any) => {
  dataSupplyTab.value = key
  const find: any = dataSupply.value.find((item) => item.key === dataSupplyTab.value)
  dataSupplyType.value = find?.type
  columns.value = [
    { title: '任务名称', dataIndex: 'taskName', key: 'taskName', width: 140 },
    { title: '文件名称', dataIndex: 'fileName', key: 'fileName', width: 160 },
    { title: `添加${dataSupplyType.value}时间`, dataIndex: 'createTime', key: 'createTime', width: 140, fixed: 'left' },
    { title: `添加${dataSupplyType.value}类型`, dataIndex: 'fileType', key: 'fileType', width: 100 },
    { title: '供给状态', dataIndex: 'status', key: 'status', width: 80 },
    { title: `添加${dataSupplyType.value}状态`, dataIndex: 'dataType', key: 'dataType', width: 100 }
  ]
  nextTick(() => {
    fetchSituation()
  })
}
/** 顶部数组 */
const fetchTopStatistic = async () => {
  try {
    const requests = [fetchHomeChangeDetail(), fetchHomeApiCount(), fetchHomeSensitiveStatistic()]
    const results = await Promise.allSettled(requests)
  } catch (error) {
    console.log(error)
  }
}
/**数据表(table_count)、字段数(field_count)、文件数(file_count) */
const fetchHomeChangeDetail = async () => {
  try {
    const res = (await getHomeChangeDetail({ data: { repositoryId: 1 } })).data
    const ress = (await getHomesql()).data
    topEntryListTotal.value.sqldata = formatToWan(ress.dbCount.count)
    topEntryListTotal.value.tableCount = formatToWan(res.table_count.count)
    topEntryListTotal.value.fieldCount = formatToWan(res.field_count.count)
    topEntryListTotal.value.fileCount = formatToWan(res.file_count.count)
  } catch (error) {
    console.log(error)
  }
}
/**API数(totalAsset)参数 */
const fetchHomeApiCount = async () => {
  try {
    const res: any = await getHomeApiCount()
    topEntryListTotal.value.apiCount = formatToWan(res.totalAsset)
  } catch (error) {
    console.log(error)
  }
}
/**涉敏数据表(sensitiveTableCount)、涉敏字段数(sensitiveFieldCount)、涉敏文件数(sensitiveFileCount) */
const fetchHomeSensitiveStatistic = async () => {
  try {
    const res = (await getHomeSensitiveStatistic({ data: { repositoryId: 1, resourceGroupId: 1, assetCategory: 'ENTITY' } })).data
    topEntryListTotal.value.sensitiveTableCount = formatToWan(res.sensitiveTableCount)
    topEntryListTotal.value.sensitiveFieldCount = formatToWan(res.sensitiveFieldCount)
    topEntryListTotal.value.sensitiveFileCount = formatToWan(res.sensitiveFileCount)
  } catch (error) {
    console.log(error)
  }
}
/**数据供给情况、添加水印供给情况、脱敏供给情况 Tab*/
const fetchSituation = async () => {
  try {
    const res = await getHomeSituation({ data: { dataType: dataSupplyTab.value } })
    dataSupplyList.value = res.data
    dataSupplyTable.value?.setDataSource(res.data.details)
  } catch (error) {
    console.log(error)
  }
}
/** 敏感数据类型分布 */
const fetchHomeDataTypeStatistic = async () => {
  try {
    const res = await getHomeDataTypeStatistic({ data: { topNum: 50, dataObjTypeEnum: 'FIELD', repositoryId: 1 } })
    dataTypeStatisticList.value = res.data.map((item: any) => {
      return {
        name: item.dataTypeName,
        value: item.count
      }
    })
  } catch (error) {
    console.log(error)
  }
}
/**等级统计 */
const fetchHomeRiskLevelTrendLast5Days = async () => {
  try {
    const res: any = await getHomeRiskLevelTrendLast5Days({ data: { repositoryId: 1 } })
    dataTrend.value = res
  } catch (error) {
    console.log(error)
  }
}
/** 类型统计 */
const fetchHomeListTop5EventType = async () => {
  try {
    const res: any = await getHomeListTop5EventType({ data: { repositoryId: 1 } })
    dataTypeRanking.value = res.sort((a: any, b: any) => a.count - b.count)
  } catch (error) {
    console.log(error)
  }
}
/**处理统计 */
const fetchHomeStatisticsEventDealStatus = async () => {
  try {
    const res: any = await getHomeStatisticsEventDealStatus({ data: { repositoryId: 1 } })
    top5EventType.value = { ...res, totalRate: ((res?.dealedCount / res?.totalCount) * 100).toFixed(2) }
  } catch (error) {
    console.log(error)
  }
}
/**
 *
 * @param value
 * 以万为单位时保留 2 位小数 并四舍五入；
 * 非法输入返回 0
 */
function formatToWan(value: number | string | null | undefined): string {
  const decimals = 2
  const threshold = 10000

  if (value === null || value === undefined || value === '') return '0'

  const num = typeof value === 'string' ? Number(String(value).replace(/,/g, '')) : Number(value)
  if (!Number.isFinite(num)) return '0'

  const sign = num < 0 ? '-' : ''
  const absNum = Math.abs(num)

  // >= threshold：转为万并四舍五入到 decimals 位（固定显示 decimals 位）
  if (absNum >= threshold) {
    const inWan = absNum / 10000
    const factor = Math.pow(10, decimals)
    const rounded = Math.round(inWan * factor) / factor
    return `${sign}${rounded.toFixed(decimals)}万`
  }

  // < threshold：最多保留 decimals 位，去掉多余的尾 0，
  const factor2 = Math.pow(10, decimals)
  const roundedOrig = Math.round(absNum * factor2) / factor2
  const s = roundedOrig.toFixed(decimals).replace(/\.?0+$/, '') // 去掉尾 0
  return `${sign}${s}`
}
onMounted(() => {
  fetchTopStatistic()
  fetchHomeDataTypeStatistic()
  fetchSituation()
  fetchHomeRiskLevelTrendLast5Days()
  fetchHomeListTop5EventType()
  fetchHomeStatisticsEventDealStatus()
})
</script>
<style lang="scss">
@keyframes arrowMoveRight {
  0% {
    left: -20px;
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    left: 20%;
    opacity: 0;
  }
}

@keyframes arrowMoveLeft {
  0% {
    right: -20px;
    opacity: 0;
  }
  20% {
    opacity: 1;
  }
  80% {
    opacity: 1;
  }
  100% {
    right: 20%;
    opacity: 0;
  }
}
.dashboard {
  height: 100%;
  overflow: auto;
  background-color: #021a4a;
  .top-entry-list {
    display: flex;
    padding: 10px;
    margin: 0 -5px;
    overflow: hidden;
    .top-entry__item {
      flex: 1;
      padding: 0 5px;
      &-inner {
        display: flex;
        align-items: center;
        padding: 10px;
        background: linear-gradient(to right, #5bd0f8, #133981);
        border-radius: 8px;
      }
      .top-entry__item-image {
        width: 50px;
        height: 50px;
        margin-right: 10px;
        img {
          width: 100%;
          height: 100%;
        }
      }
      .top-entry__item-content {
        .title {
          margin: 0;
          font-size: 14px;
          font-weight: normal;
          color: #f1f1f1;
        }
        .num {
          margin: 5px 0 0;
          font-size: 14px;
          color: #fff;
        }
      }
    }
  }
  // 数据中心
  .data-center-sidebar {
    display: flex;
    height: 500px;
    padding: 0 10px;
    .data-center-display {
      position: relative;
      flex: 4;
      height: 100%;
      padding: 10px;
      background-color: #11143d;
      border-radius: 8px;
      .data-center-bg {
        width: 100%;
        height: 100%;
      }
      .data-info {
        position: absolute;
        z-index: 101;
        width: 20%;
        .info-item {
          .text {
            font-size: 14px;
            color: rgb(58 134 255 / 50%);
          }
        }
        .top-info-item {
          margin-top: 0;
        }
        .bottom-info-item {
          margin-top: 190px;
        }
        &.right-data-info {
          top: 24%;
          left: 71%;
        }
      }
      .arrow-wrap {
        position: absolute;
        z-index: 100;
        width: 10%;
        &.left-arrow-wrap {
          top: 24%;
          left: 16%;
        }
        &.right-arrow-wrap {
          top: 24%;
          right: 20%;
        }
        .arrow-item {
          position: relative;
          width: 100%;
          .arrow-pic {
            width: 100%;
          }
          .text {
            position: absolute;
            top: 50%;
            width: 100%;
            padding: 0 10px;
            font-weight: normal;
            color: #fff;
            transform: translateY(-50%);
          }
        }
        .left-arrow-item {
          animation: arrowMoveLeft 4s linear infinite;
          .text {
            text-align: right;
          }
        }
        .right-arrow-item {
          animation: arrowMoveRight 4s linear infinite;
        }
      }
    }
    .right-wrap {
      flex: 1;
      margin-left: 10px;
      overflow: hidden;
      .right-title {
        font-size: 16px;
        color: #fff;
      }
      .right-tools {
        height: 240px;
        padding: 10px;
        margin-bottom: 10px;
        overflow: hidden;
        background-color: #11143d;
        border-radius: 8px;
      }
      .tools-list {
        display: flex;
        flex-wrap: wrap;
        margin-top: 10px;
        .tools-item {
          display: flex;
          flex-direction: column;
          align-items: center;
          justify-content: center;
          width: 33.3333%;
          padding: 10px;
          white-space: nowrap;
          .icon {
            width: 40px;
            height: 40px;
          }
          .text {
            margin: 5px 0 0;
            font-size: 12px;
            color: #fff;
          }
        }
      }
      .right-chart {
        height: 250px;
        padding: 10px;
        margin-top: 10px;
        background-color: #11143d;
        border-radius: 8px;
        .chart-box {
          height: 200px;
        }
      }
    }
  }
  // 图标和数据
  .data-table-wrap {
    display: flex;
    margin: 10px 5px 0;
    .data-table-item {
      position: relative;
      flex: 1;
      width: 50%;
      margin: 0 5px 10px;
      background-color: #11143d;
      border-radius: 8px;
      .ant-tabs-nav::before {
        border-bottom: none;
      }
      .ant-tabs-nav {
        padding: 0 10px;
        .ant-tabs-tab-btn {
          color: #eee;
        }
        .ant-tabs-tab-active {
          font-weight: bold;
          color: #fff;
          background-color: transparent;
        }
      }
      .data-info-list {
        display: flex;
        margin: 0 5px;
        overflow: hidden;
        .data-info__item {
          flex: 1;
          padding: 0 5px;
          &-inner {
            display: flex;
            align-items: center;
            padding: 10px;
            background-color: #1d2e69;
            border: 1px solid #2543a0;
            border-radius: 8px;
          }
          .info {
            flex: 1;
            .title {
              margin: 0;
              font-size: 14px;
              font-weight: normal;
              color: #f1f1f1;
            }
            .num {
              margin: 5px 0 0;
              font-size: 14px;
              font-weight: bold;
              color: #fff;
            }
          }
          .icon {
            width: 48px;
            height: 48px;
          }
        }
      }
      .table-wrapper {
        margin: 10px;
        color: #fff;
        .ant-table {
          background-color: #0f1b3d;
        }
        .ant-table-header,
        .ant-table-header table {
          border-radius: 0;
        }
        .ant-table-thead > tr > th {
          font-size: 12px;
          color: #fff;
          background: #29304f;
          border-bottom: none;
          border-radius: 0;
        }
        .ant-table-tbody > tr > td {
          font-size: 12px;
          color: #fff;
          background: #0f1b3d;
          border-top: none;
          border-bottom: 1px solid #1e2f4d;
        }
        .ant-table-cell {
          padding: 6px;
        }
        .ant-table-cell::before {
          display: none;
        }
        .ant-table-cell-scrollbar {
          background-color: #29304f;
          box-shadow: none;
        }
        .ant-table-body::-webkit-scrollbar {
          display: none;
        }
        .ant-table-tbody > tr:hover > td {
          background: #0f1b3d;
        }
        .status-online {
          display: inline-block;
          padding: 2px 8px;
          color: #00c292;
          background-color: rgb(0 194 146 / 10%);
          border-radius: 4px;
        }
        .status-offline {
          display: inline-block;
          padding: 2px 8px;
          color: #f75a5a;
          background-color: rgb(247 90 90 / 10%);
          border-radius: 4px;
        }
        .status-success {
          margin-left: 4px;
          color: #00c292;
        }
        .status-fail {
          margin-left: 4px;
          color: #f75a5a;
        }
        .dot {
          display: inline-block;
          width: 8px;
          height: 8px;
          border-radius: 50%;
        }
        .dot-success {
          background-color: #00c292;
        }
        .dot-fail {
          background-color: #f75a5a;
        }
        .detail-link {
          color: #3a86ff;
          text-decoration: underline;
          cursor: pointer;
        }
      }
      .chart-wrap {
        display: flex;
        padding: 10px 5px 0;
        .chart-item {
          flex: 1;
          height: 245px;
          padding: 10px;
          margin: 0 5px;
          background-color: #021b4b;
          border-radius: 8px;
          .chart-box {
            height: 100%;
          }
        }
      }
    }
  }
}
.white-text {
  color: #fff;
}
</style>
